package main

import (
	"encoding/json"
	"fmt"
	"strings"
)

type coordinate struct {
	d, m, s float64
	h       rune
}

type Rovers struct {
	name, site string
	lat, lon   coordinate
}

func (c coordinate) decimal() float64 {
	sign := 1.0
	switch c.h {
	case 'S', 'W', 's', 'w':
		sign = -1
	}
	return sign * (c.d + c.m/60 + c.s/3600)
}

func (c coordinate) MarshalJSON() ([]byte, error) {
	type myCoordinate struct {
		Dec float64 `json:"decimal"`
		Dms string  `json:"dms"`
		D   float64 `json:"degrees"`
		M   float64 `json:"minutes"`
		S   float64 `json:"seconds"`
		H   string  `json:"hemisphere"`
	}
	return json.Marshal(myCoordinate{c.decimal(), c.String(), c.d, c.m, c.s, strings.ToUpper(string(c.h))})
}

func (c coordinate) String() string {
	return fmt.Sprintf("%v° %v′ %v″ %v", c.d, c.m, c.s, strings.ToUpper(string(c.h)))
}

func (r Rovers) String() string {
	return fmt.Sprintf("%v is at %v %v, %v", r.name, r.site, r.lat.String(), r.lon.String())
}

func initRovers(name, site string, lat, long coordinate) Rovers {
	return Rovers{name: name, site: site, lat: lat, lon: long}
}

func main() {
	rover := initRovers("insight", "ely", coordinate{4, 30, 0.2, 'n'}, coordinate{135, 54, 0.0, 'e'})
	fmt.Println(rover)

	c := coordinate{135, 54, 0.0, 'e'}

	ft, _ := json.Marshal(c)
	fmt.Printf(string(ft))
}
